SNSとSQSのFanoutで、メッセージが並列に届くことを確認してみた
SNSとSQSを組み合わせるファンアウトはよく使われます。いざ、実際に使うときになって、ふと思ってしまいました。
「あれ? 同じデータが来るよね? 一部だけじゃないよね?」と。
99%問題なしと思っていますが、念のため、実際に試してみました。
おすすめの方
- SNSとSQSのファンアウトで並列にイベント実行されるか知りたい方
- SNSとSQSのファンアウトをCloudFormatinで作成したい方
実験用のサーバーレスアプリを作成する
ざっくり構成図
1つのSNSに2つのSQSと2つのLambdaを繋げます。このときのLambdaのログを確認します。
sam init
sam init \ --runtime python3.8 \ --name sns-sqs-test \ --app-template hello-world \ --package-type Zip
SAMテンプレート
下記を作成しています。
- SNSトピック
- SQS
- SQSポリシー
- Lambda1とロググループ
- Lambda2とロググループ
なお、Lambda1とLambda2は、同じソースコードを使用します。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: sns-sqs-test Resources: # SNS TestTopic: Type: AWS::SNS::Topic Properties: Subscription: - Protocol: sqs Endpoint: !GetAtt Test1Queue.Arn - Protocol: sqs Endpoint: !GetAtt Test2Queue.Arn # SQS Test1Queue: Type: AWS::SQS::Queue Properties: VisibilityTimeout: 10 Test2Queue: Type: AWS::SQS::Queue Properties: VisibilityTimeout: 10 QueuePolicy: Type: AWS::SQS::QueuePolicy Properties: Queues: - !Ref Test1Queue - !Ref Test2Queue PolicyDocument: Statement: - Action: - "sqs:SendMessage" Effect: "Allow" Resource: "*" Principal: Service: sns.amazonaws.com # Lambda Test1Function: Type: AWS::Serverless::Function Properties: CodeUri: hello_world/ Handler: app.lambda_handler Runtime: python3.8 Timeout: 10 Events: SQS: Type: SQS Properties: BatchSize: 1 Queue: !GetAtt Test1Queue.Arn Test1FunctionLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub /aws/lambda/${Test1Function} Test2Function: Type: AWS::Serverless::Function Properties: CodeUri: hello_world/ Handler: app.lambda_handler Runtime: python3.8 Timeout: 10 Events: SQS: Type: SQS Properties: BatchSize: 1 Queue: !GetAtt Test2Queue.Arn Test2FunctionLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub /aws/lambda/${Test2Function}
Lambdaコード
event
の内容をログ出力するだけです。
import json def lambda_handler(event, context): print(json.dumps(event))
デプロイ
sam build sam deploy \ --stack-name Sns-Sqs-Test-Stack \ --s3-bucket cm-fujii.genki-deploy \ --capabilities CAPABILITY_NAMED_IAM \ --no-fail-on-empty-changeset
SNSでメッセージを発行して、動作を確認する
SNSトピックにメッセージを発行する
1つのメッセージを発行します。2つのLambdaに同じメッセージが届くことを期待します。
Lambda1のログを確認する
バッチリ届いていました。
Lambda2のログを確認する
2つ目のLambdaにも、問題なく届いていました。
というわけで、メッセージは並列に届く
さいごに
SNSとSQSを組合わあせたアーキテクチャについては、下記のブログが非常に参考になります。ぜひご覧ください。